#include <iostream>
#include <fstream>
#include <cstdio>
#include <json/json.h>
#include "spline.h"
using namespace std;
class F : public Function
{
public:
  double operator()(const double& x) const {return 1 / (1 + x * x);}
  double derivative(const double& x) const {return -2 * x / (1 + x * x) / (1 + x * x);}
  double sec_derivative(const double& x) const {return 2 * (3 * x * x - 1) / pow(1 + x * x, 3);}
}f;

int main()
{
  ifstream ifs("C.json");
  Json::Reader reader;
  Json::Value obj;
  reader.parse(ifs, obj);
  vector<double> x1, x2;
  for (int i = 0;i < obj["x1"].size();i++) x1.push_back(obj["x1"][i].asDouble());
  for (int i = 0;i < obj["x2"].size();i++) x2.push_back(obj["x2"][i].asDouble());

  double L = obj["L"].asDouble();
  double R = obj["R"].asDouble();

  FILE* file = nullptr;
  if (freopen_s(&file, "../data/C.out", "w", stdout) != 0) 
    cerr << "error: File opening failure" << endl, exit(-1);
  for (double X = L;X <= R;X += 0.001) printf("%lf,", f(X));
  printf("%lf,", f(R));puts("");
  B_spline_interpolation cubic(f, x1, 3, 1);
  B_spline_interpolation quadratic(f, x2, 2, 1);
  cubic.solve();
  quadratic.solve();
  for (double X = L;X <= R;X += 0.001) printf("%lf,", cubic(X));
  printf("%lf,", cubic(R));puts("");
  for (double X = L;X <= R;X += 0.001) printf("%lf,", quadratic(X));
  printf("%lf,", quadratic(R));puts("");
  fclose(stdout);

  if (freopen_s(&file, "../data/D.out", "w", stdout) != 0) 
    cerr << "error: File opening failure" << endl, exit(-1);
  for (double X = L;X <= R;X += 0.001) printf("%lf,", fabs(f(X) - cubic(X)));
  printf("%lf,", fabs(f(R) - cubic(R)));puts("");
  for (double X = L;X <= R;X += 0.001) 
    printf("%lf,", fabs(f(X) - quadratic(X)));
  printf("%lf,", fabs(f(R) - quadratic(R)));puts("");
  fclose(stdout);
  return 0;
}
